package com.lsismo.core.base.dao.hibernate;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.lsismo.core.base.dao.UniversalDao;

/**
 * 该类用于对象的CRUD，但不需要任何Spring配置，唯一的负面影响是它需要进行对象之间的强制转换
 *
 */
public class UniversalDaoHibernate extends HibernateDaoSupport implements UniversalDao {
    /**
     * 作用于所有子类的Log变量
     */
    protected final Log log = LogFactory.getLog(getClass());

    /**
     * {@inheritDoc}
     */
    public Object save(Object o) {
        return getHibernateTemplate().merge(o);
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
	public Object get(Class clazz, Serializable id) {
        Object o = getHibernateTemplate().get(clazz, id);

        if (o == null) {
            throw new ObjectRetrievalFailureException(clazz, id);
        }

        return o;
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
	public List getAll(Class clazz) {
        return getHibernateTemplate().loadAll(clazz);
    }    
   
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
	public boolean exists(Class clazz,Serializable id) {
    	Object o = getHibernateTemplate().get(clazz, id);
        return o != null;
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
	public void remove(Class clazz, Serializable id) {
        getHibernateTemplate().delete(get(clazz, id));
    }
    
    /**
     * {@inheritDoc}
     */
    public void remove(Object o) {
        getHibernateTemplate().delete(o);
    }
    
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
	public List findByExample(Object o)  {
    	return super.getHibernateTemplate().findByExample(o);
    }
    
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public List findByProperty(Class clazz, String propertyName, Object value)  {
    	String queryString = "from " + clazz.getName() + " as model where model." + propertyName + "= ?";
    	return (List)getHibernateTemplate().find(queryString, value);
    }
    
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
	public List find(String hql, Object...values)  {
        return super.getHibernateTemplate().find(hql, values);
    }
    
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public List getAllDistinct(Class clazz) {
        Collection result = new LinkedHashSet(getAll(clazz));
        return new ArrayList(result);
    }
	
    /**
     * {@inheritDoc}
     */
	@SuppressWarnings("unchecked")
	public List findByNamedQuery(String queryName, Map<String, Object> queryParams)throws Exception {
       String []params = new String[queryParams.size()];
       Object []values = new Object[queryParams.size()];
       int index = 0;
       Iterator<String> i = queryParams.keySet().iterator();
       while (i.hasNext()) {
           String key = i.next();
           params[index] = key;
           values[index++] = queryParams.get(key);
       }
       return getHibernateTemplate().findByNamedQueryAndNamedParam(
           queryName, 
           params, 
           values);
    }

}
